
#ifndef TOPOTREEMODEL_H
#define TOPOTREEMODEL_H

#include <QAbstractItemModel>
#include <QObject>

#include <boost/json.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

namespace solar
{
    class ParaTreeModel;
    class ParaTreeViewController;
    class TopoTreeNode;
    class TopoTreeModel : public QAbstractItemModel
    {
            Q_OBJECT

            enum nodeRoles
            {
                NAME = Qt::UserRole + 1,
                TYPE
            };

        public:
            explicit TopoTreeModel(QObject* parent = nullptr);
            ~TopoTreeModel();

            void appendChild(const QModelIndex& index, const QList<QVariant>& data_list, int count,
                             QSharedPointer<ParaTreeModel>& para_tree_model);
            auto appendChild(const QModelIndex& index, int type, int count,
                             QSharedPointer<ParaTreeModel>& para_tree_model) -> bool;
            void setNodeName(const QString& append_name, QModelIndex index);

            [[nodiscard]] auto
            columnCount(const QModelIndex& parent = QModelIndex()) const -> int override;
            [[nodiscard]] auto
            rowCount(const QModelIndex& parent = QModelIndex()) const -> int override;
            [[nodiscard]] auto roleNames() const -> QHash<int, QByteArray> override;
            [[nodiscard]] auto data(const QModelIndex& index, int role) const -> QVariant override;
            [[nodiscard]] auto flags(const QModelIndex& index) const -> Qt::ItemFlags override;
            [[nodiscard]] auto
            index(int row, int column,
                  const QModelIndex& parent = QModelIndex()) const -> QModelIndex override;
            [[nodiscard]] auto parent(const QModelIndex& index) const -> QModelIndex override;

            // 获取该项对应的类型的图片名
            [[nodiscard]] auto getType(const QModelIndex& index) const -> QString;
            // 返回总共的节点数--遍历一下树
            [[nodiscard]] auto getTotalNodeCnt() const -> qsizetype;

            // 获得根节点的para_tree_model
            auto getParaTreeModelAboutFirstNode() -> QSharedPointer<ParaTreeModel>;

            /**
             * 通过文件设置topo
             */
            void setTopoModelViaFile(boost::property_tree::ptree& field_tree,
                                     QSharedPointer<ParaTreeViewController> para_tree_controller);
            void
            appendRevChildViaPTree(QSharedPointer<TopoTreeNode>& first_node,
                                   boost::property_tree::ptree& tree,
                                   QSharedPointer<ParaTreeViewController> para_tree_controller);
            void
            appendHelioChildViaPTree(QSharedPointer<TopoTreeNode>& first_node,
                                     boost::property_tree::ptree& tree,
                                     QSharedPointer<ParaTreeViewController> para_tree_controller);
            auto appendChild(QSharedPointer<TopoTreeNode>& parent,
                             boost::property_tree::ptree& tree, int type, QString name,
                             QSharedPointer<ParaTreeViewController> para_tree_controller)
                -> QSharedPointer<TopoTreeNode>;
            /**
             * 以下用于rayTracing的参数传递
             */
            auto getRootNode() -> TopoTreeNode*;

        private:
            // appendChild中调用，返回与父节点下的兄弟节点都不同的name
            auto getUniqueName(TopoTreeNode* parent_node, int type) -> QString;

            // 在appendChild中调用，在添加新的孩子节点时，生成ParaTreeModel
            void createParaTreeModel(int type, QSharedPointer<ParaTreeModel>& para_tree_model);

            QSharedPointer<TopoTreeNode> root_node;
            QHash<int, QByteArray> role_names_; // 即roleNames
    };

} // namespace solar

#endif // TOPOTREEMODEL_H
